package keter.web.security;

import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;

import keter.dao.org.AccountDao;
import keter.domain.Account;
import keter.domain.Role;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.Assert;


/**
 * Adapts User model from pl.edu.agh.mea.domain package to make it usable in
 * Spring Security authentication mechanism.
 * 将Account转换为Spring的User
 * @author Dawid Fatyga
 * 
 */
public class AccountAdapter implements UserDetails {
	private static final long serialVersionUID = 1L;

	transient private Account account;
	transient private AccountDao accountDao;
	
	public AccountAdapter() {
	}

	public AccountAdapter(Account account, AccountDao accountDao) {
		this.account = account;
		this.accountDao = accountDao;
	}

	/**
	 * Converts collection of Authorities into collection of GrantedAuthorities
	 * usable in authentication mechanism.
	 * 
	 * @param authorities
	 *            collection of authorities
	 * @return collection of granted authorities
	 */
	private Collection<GrantedAuthority> toGrantedAuthorities(Collection<Role> authorities) {
		Set<GrantedAuthority> grantedAuthorities = new TreeSet<GrantedAuthority>();
		for (Role authority : authorities) {
			grantedAuthorities.add(new AuthorityAdapter(authority));
		}
		return grantedAuthorities;
	}

	public void setAccount(Account account){
		this.account = account;
	}

	/**
	 * Returns user delegate.
	 * 
	 * @return cached user instance
	 */
	public Account getAccount(){
		return getAccount(false);
	}

	/**
	 * @param force
	 *            allows to fetch user from database (not from cache)
	 * @return user instance
	 */
	public Account getAccount(boolean force) {
		if (force) {
		    Assert.notNull(account);
		    Assert.notNull(accountDao);
			account = accountDao.findOne(account.getId());
		}
		return account;
	}

	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		return toGrantedAuthorities(account.getRoleList());
	}

	@Override
	public String getPassword() {
		return account.getPassword();
	}

	@Override
	public String getUsername() {
		return account.getName();//系统采用“账号”作为登录验证
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		//TODO:从数据库中读取
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		//TODO:从数据库中读取
		return true;
	}

	public void setUserDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}

	/**
	 * An alias for hasRole(), but accepts Authority enum.
	 */
	public boolean is(Role role) {
		return is(role.getName().toString());
	}

	/**
	 * An alias for hasRole()
	 */
	public boolean is(String name) {
		return hasRole(name);
	}

	/**
	 * Searches for grantedAuthority with given name, and returns true if
	 * exists.
	 * 
	 * @param name
	 *            name of a granted authority
	 * @return true if authority exists
	 */
	public boolean hasRole(String name) {
		return getAuthorities().contains(new AuthorityAdapter(name));
	}
}